#ifndef __OPENCV_CORE_DEVPTRS_HPP__
#define __OPENCV_CORE_DEVPTRS_HPP__

#ifdef __cplusplus

#include "cuda_runtime.h"

namespace cv
{
    namespace cuda
    {
        template <typename T> struct DevMem2D_
        {
            int cols;
            int rows;
            T* data;
            size_t step;

            DevMem2D_() : cols(0), rows(0), data(0), step(0) {}
            DevMem2D_(int rows_, int cols_, T* data_, size_t step_)
                : cols(cols_), rows(rows_), data(data_), step(step_) {}

            template <typename U>
            explicit DevMem2D_(const DevMem2D_<U>& d)
                : cols(d.cols), rows(d.rows), data((T*)d.data), step(d.step) {}

            typedef T elem_type;
            enum { elem_size = sizeof(elem_type) };

            __host__ __device__ __forceinline__ size_t elemSize() const { return elem_size; }
            __host__ __device__ __forceinline__ T* ptr(int y = 0) { return (T*)((char*)data + y * step); }
            __host__ __device__ __forceinline__ const T* ptr(int y = 0) const { return (const T*)((const char*)data + y * step); }
            __host__ __device__ __forceinline__ operator T* () const { return data; }

            DevMem2D_<T>& operator = (cv::cuda::GpuMat& src) {
                rows = src.rows;
                cols = src.cols;
                step = src.step;
                data = reinterpret_cast<T*>(src.data);
                return *this;
            };
        };

        typedef DevMem2D_<unsigned char> DevMem2Db;
        typedef DevMem2Db DevMem2D;
        typedef DevMem2D_<float> DevMem2Df;
        typedef DevMem2D_<int> DevMem2Di;
    }
}

#endif // __cplusplus

#endif /* __OPENCV_CORE_DEVPTRS_HPP__ */
